﻿Imports System.ComponentModel
Imports System.IO
Imports org.codegen.common.ProgressIndicator
Imports org.codegen.common.Encryption

Public Class DBBackup

    Public Event BackupFinished(ByVal sender As Object)

    Public Property wasCancelled As Boolean
    Public Property exitAfterBackup As Boolean

    Private progress As BackroundProgressIndicator.BackroundProgressIndicator
    Private backupFilename As String
    Private zipFilename As String

    Private Property backgroundWorker As BackgroundWorker

    Public Sub doBackup()

        Me.backupFilename = SimpleEncrypt.Decipher(My.Settings.dbBackupDir) & _
                    My.Settings.dbName & ".bak"

        Me.zipFilename = backupFilename & ".zip"

        Me.progress = New BackroundProgressIndicator.BackroundProgressIndicator
        Me.progress.showCancel = True
        Me.progress.Start(AddressOf compressAndUploadBackupFile)

    End Sub

    Private Sub prgStarted(ByVal sender As Object, ByVal e As ProgressableEventArgs)

    End Sub

    Private Sub ftpFileUploadProgress(ByVal sender As Object, ByVal e As ProgressableEventArgs)

        Me.backgroundWorker.ReportProgress( _
                CInt((e.currentStep / e.totalSteps) * 100), _
                e.currentStep & " bytes of total " & e.totalSteps & " processed...")

        If Me.backgroundWorker.CancellationPending Then
            e.wasCancelled = True
            Me.backgroundWorker.CancelAsync()

        End If

    End Sub

    Private Sub ftpFileUploadFinished(ByVal sender As Object, ByVal e As ProgressableEventArgs)

    End Sub

    Private Sub compressAndUploadBackupFile(ByVal sender As Object, ByVal e As DoWorkEventArgs)

        Me.backgroundWorker = CType(sender, BackgroundWorker)

        Dim backupSqlTemplate = <backupSql>
BACKUP DATABASE {0} 
TO  DISK = N'{1}'
WITH NOFORMAT, INIT,  NAME = N'{0}-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
</backupSql>

        progress.progressWindowTitle = "Backup Database"

        Dim backupSqlCommand = String.Format(backupSqlTemplate.Value, My.Settings.dbName, backupFilename)
        Call DBUtils.Current.executeSQL(backupSqlCommand)

        Dim zp As New ZipFileCreator

        AddHandler zp.FileCompressionStart, AddressOf prgStarted
        AddHandler zp.FileCompressionProgress, AddressOf ftpFileUploadProgress
        AddHandler zp.FileCompressionFinished, AddressOf ftpFileUploadFinished

        Dim lNewFileInfo As FileInfo = New FileInfo(Me.zipFilename)
        progress.progressWindowTitle = "Compressing backup file " & lNewFileInfo.Name

        zp.AddFileToZip(Me.zipFilename, Me.backupFilename)

        If zp.wasCancelled Then
            Me.wasCancelled = True
            Exit Sub
        End If


        progress.progressWindowTitle = "Uploading backup file " & lNewFileInfo.Name

        Dim f As FTPClient = New FTPClient()
        Try
            f.RemoteHost = SimpleEncrypt.Decipher(My.Settings.ftphost)
            f.RemoteUser = SimpleEncrypt.Decipher(My.Settings.ftpRemoteUser)
            f.RemotePassword = SimpleEncrypt.Decipher(My.Settings.ftpRemotePassword)
            f.RemotePath = SimpleEncrypt.Decipher(My.Settings.ftpBackupDir)
            f.Login()
            f.ChangeDirectory(SimpleEncrypt.Decipher(My.Settings.ftpBackupDir))
            f.SetBinaryMode(True)

            AddHandler f.FileUploadStart, AddressOf prgStarted
            AddHandler f.FileUploadProgress, AddressOf ftpFileUploadProgress
            AddHandler f.FileUploadFinished, AddressOf ftpFileUploadFinished

            f.UploadFile(zipFilename)

            Me.wasCancelled = f.wasCancelled

        Finally
            f.CloseConnection()
        End Try

        progress.EndProcess()

        RaiseEvent BackupFinished(Me)

    End Sub

End Class
